<template>
	<el-form label-position="left" size="small" :inline="compLayout" :model="ruleForm" v-if="options.type === 'edit'" ref="formRef"
		:style="!compLayout && {
			display: 'flex',
			'justify-content': 'space-between',
			'align-items': 'flex-start',
			'flex-flow': 'wrap',
			width: props.options.width,
		}
			">
		<!-- 表单内容 -->
		<el-form-item :style="[
			!compLayout && { marginRight: '0px', display: 'inline-flex' },
			{ width: item.width || (!compLayout && '100%') },
		]" :label-width="form.labelWidth" :label="item.label" v-for="(item, index) in form.options" :prop="item.key"
			:rules="item.rule" :key="index" :class="item.rule || 'not-rule'">
			<component style="width: 100%" v-if="item?.component" :is="FormChildComp[item.component]"
				:configure="{ ...item, ...item.conf }" v-model="ruleForm[item.key]" @onChange="onChange($event, item.key)">
			</component>
		</el-form-item>
		<!-- 按钮内容 -->
		<el-form-item v-if="form.btnList?.length">
			<div>
				<PyButton v-for="(btn, i) in form.btnList" :key="i" :configure="{
					text: btn.label,
					type: btn.type,
					icon: btn.icon,
					disabled: btn.disabled,
					click: btn.click,
				}"></PyButton>
			</div>
		</el-form-item>
	</el-form>
	<!-- 预览 -->
	<FormDesc :options="form" v-if="options.type === 'preview'"></FormDesc>
</template>

<script lang="ts" setup>
import { ref, onMounted, Ref, watch, computed } from "vue";
import { BasicFormOptions } from "./type";
import FormDesc from "./form-desc.vue";
import { PyButton } from "./components/PyButton";
import { FormInstance } from "element-plus";
import { FormChildComp } from "./components";

const props = defineProps<{
	options: BasicFormOptions<Record<string, any>> & {
		change: (key: string, value: any) => void;
		init: (ref: FormInstance) => void;
	};
}>();
const form = ref(props.options);
const onChange = (v: string | number, k: string) => {
	props.options.change(k, v);
	ruleForm.value[k] = v;
};

//表单Ref
const formRef = ref<FormInstance>();
const ruleForm: Ref<{ [key: string]: any }> = ref({});

//转换校验规则与表单数据模型
const convertFormObj = () => {
	form.value.options.forEach(item => {
		ruleForm.value[item.key] = item.value;
	});
};
convertFormObj();

//计算水平方向还是垂直方向
const compLayout = computed(() => {
	return form.value.layout === "horizontal" ? true : false;
});

/** 监听配置的更改进行数据的转换 */
watch(
	() => props.options,
	val => {
		console.log('form-watch');

		if (form.value.options && form.value.options.length) {
			convertFormObj();
		}
		form.value = { ...val };
	}
);

onMounted(() => {
	props.options.init(formRef.value as FormInstance);
});

</script>

<style lang="scss" scoped>
.not-rule {
	:deep(.el-form-item__label) {
		&::before {
			content: " ";
			margin-right: 9px;
		}
	}
}
</style>
